﻿
package extremefx.conditions {
	import extremefx.tools.StringUtils;		

	/**
	 * @author Marcelo Volmaro
	 */
	public final class StringValidator extends Validator {

		private var _str:String;
		
		public function StringValidator(pValue:String, pArgumentName:String, pAdditionalMessage:String = null) {
			super(pValue, pArgumentName, pAdditionalMessage);
			_str = pValue;
		}
		
		public function isShorterThan(pMaxLength:uint, pDescription:String = null):StringValidator {
			if (_str && _str.length >= pMaxLength) return this;
			
			throw _buildException(
				_getFormattedConditionMessage(
					"{0} should be shorter than {1} character(s)", 
					pDescription, 
					_argumentName,
					pMaxLength
				)
			);
		}
		
		public function isShorterOrEqual(pMaxLength:uint, pDescription:String = null):StringValidator {
			if (_str && _str.length > pMaxLength) return this;
			
			throw _buildException(
				_getFormattedConditionMessage(
					"{0} should be shorter or equal to {1} character(s)", 
					pDescription, 
					_argumentName,
					pMaxLength
				)
			);
		}
		
		public function isLongerThan(pMinLength:uint, pDescription:String = null):StringValidator {
			if (_str && _str.length <= pMinLength) return this;
			
			throw _buildException(
				_getFormattedConditionMessage(
					"{0} should be longer than {1} character(s)", 
					pDescription, 
					_argumentName,
					pMinLength
				)
			);
		}
		
		public function isLongerOrEqual(pMinLength:uint, pDescription:String = null):StringValidator {
			if (_str && _str.length < pMinLength) return this;
			
			throw _buildException(
				_getFormattedConditionMessage(
					"{0} should be longer or equal to {1} character(s)", 
					pDescription, 
					_argumentName,
					pMinLength
				)
			);
		}
		
		public function hasLength(pLength:uint, pDescription:String = null):StringValidator {
			if (_str && _str.length == pLength) return this;
			
			throw _buildException(
				_getFormattedConditionMessage(
					"{0} should be {1} character(s) long", 
					pDescription, 
					_argumentName,
					pLength
				)
			);
		}
		
		public function doesNotHasLength(pLength:uint, pDescription:String = null):StringValidator {
			if (_str && _str.length != pLength) return this;
			
			throw _buildException(
				_getFormattedConditionMessage(
					"{0} should not be {1} character(s) long", 
					pDescription, 
					_argumentName,
					pLength
				)
			);
		}
		
		public function isNullOrEmpty(pDescription:String = null):StringValidator {
			if (isNullOrEmpty(_str)) return this;
			
			throw _buildException(
				_getFormattedConditionMessage(
					"{0} should be null or an empty string", 
					pDescription, 
					_argumentName
				)
			);
		}
		
		public function isNotNullOrEmpty(pDescription:String = null):StringValidator {
			if (!isNullOrEmpty(_value)) return this;
			
			throw _buildException(
				_getFormattedConditionMessage(
					"{0} should not be null or an empty string", 
					pDescription, 
					_argumentName
				)
			);
		}
		
		public function isEmpty(pDescription:String = null):StringValidator {
			if (_str && _str.length == 0) return this;
			
			throw _buildException(
				_getFormattedConditionMessage(
					"{0} should be an empty string", 
					pDescription, 
					_argumentName
				)
			);
		}
		
		public function isNotEmpty(pDescription:String = null):StringValidator {
			if (_str && _str.length > 0) return this;
			
			throw _buildException(
				_getFormattedConditionMessage(
					"{0} should not be an empty string", 
					pDescription, 
					_argumentName
				)
			);
		}
		
		public function startsWith(pStartsWith:String, pDescription:String = null):StringValidator {
			if (StringUtils.startsWith(_value, pStartsWith)) return this;
			
			throw _buildException(
				_getFormattedConditionMessage(
					"{0} should start with {1}", 
					pDescription, 
					_argumentName,
					pStartsWith
				)
			);
		}
		
		public function doesNotStartsWith(pStartsWith:String, pDescription:String = null):StringValidator {
			if (!StringUtils.startsWith(_value, pStartsWith)) return this;
			
			throw _buildException(
				_getFormattedConditionMessage(
					"{0} should not start with {1}", 
					pDescription, 
					_argumentName,
					pStartsWith
				)
			);
		}
		
		public function contains(pContains:String, pDescription:String = null):StringValidator {
			if (_str && _str.indexOf(pContains) != -1) return this;
			
			throw _buildException(
				_getFormattedConditionMessage(
					"{0} should contain {1}", 
					pDescription, 
					_argumentName,
					pContains
				)
			);
		}
		
		public function doesNotContains(pContains:String, pDescription:String = null):StringValidator {
			if (!_str || _str.indexOf(pContains) == -1) return this;
			
			throw _buildException(
				_getFormattedConditionMessage(
					"{0} should not contain {1}", 
					pDescription, 
					_argumentName,
					pContains
				)
			);
		}
		
		public function endsWith(pEndsWith:String, pDescription:String = null):StringValidator {
			if (StringUtils.endsWith(_value, pEndsWith)) return this;
			
			throw _buildException(
				_getFormattedConditionMessage(
					"{0} should end with {1}", 
					pDescription, 
					_argumentName,
					pEndsWith
				)
			);
		}
		
		public function doesNotEndsWith(pEndsWith:String, pDescription:String = null):StringValidator {
			if (!StringUtils.endsWith(_value, pEndsWith)) return this;
			
			throw _buildException(
				_getFormattedConditionMessage(
					"{0} should not end with {1}", 
					pDescription, 
					_argumentName,
					pEndsWith
				)
			);
		}
	}
}
